package com.conference.service.impl;

import com.conference.entity.ConferenceSchedule;
import com.conference.repository.ConferenceScheduleRepository;
import com.conference.service.ConferenceScheduleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class ConferenceScheduleServiceImpl implements ConferenceScheduleService {

    @Autowired
    private ConferenceScheduleRepository scheduleRepository;

    @Override
    @Transactional
    public ConferenceSchedule createSchedule(ConferenceSchedule schedule) {
        return scheduleRepository.save(schedule);
    }

    @Override
    @Transactional
    public ConferenceSchedule updateSchedule(ConferenceSchedule schedule) {
        return scheduleRepository.save(schedule);
    }

    @Override
    @Transactional
    public void deleteSchedule(Long id) {
        scheduleRepository.deleteById(id);
    }

    @Override
    public ConferenceSchedule getScheduleById(Long id) {
        return scheduleRepository.findById(id).orElse(null);
    }

    @Override
    public List<ConferenceSchedule> getSchedulesByConferenceId(Long conferenceId) {
        return scheduleRepository.findByConferenceId(conferenceId);
    }

    @Override
    public List<ConferenceSchedule> getSchedulesByVenueId(Long venueId) {
        return scheduleRepository.findByVenueId(venueId);
    }

    @Override
    public Page<ConferenceSchedule> searchSchedules(
        Long conferenceId,
        Long venueId,
        String title,
        String speaker,
        LocalDateTime startTime,
        LocalDateTime endTime,
        Pageable pageable
    ) {
        return scheduleRepository.findAll((Specification<ConferenceSchedule>) (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (conferenceId != null) {
                predicates.add(cb.equal(root.get("conferenceId"), conferenceId));
            }

            if (venueId != null) {
                predicates.add(cb.equal(root.get("venueId"), venueId));
            }

            if (title != null && !title.isEmpty()) {
                predicates.add(cb.like(cb.lower(root.get("title")), "%" + title.toLowerCase() + "%"));
            }

            if (speaker != null && !speaker.isEmpty()) {
                predicates.add(cb.like(cb.lower(root.get("speaker")), "%" + speaker.toLowerCase() + "%"));
            }

            if (startTime != null) {
                predicates.add(cb.greaterThanOrEqualTo(root.get("startTime"), startTime));
            }

            if (endTime != null) {
                predicates.add(cb.lessThanOrEqualTo(root.get("endTime"), endTime));
            }

            return cb.and(predicates.toArray(new Predicate[0]));
        }, pageable);
    }
} 